# Copyright (c) 2011, Ryan M. Lefever
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Include system makefile generated by configure
include system.mk

# Paths to tools
AR :=			ar
INSTALL :=		install
DOXYGEN :=		doxygen
FIX_DEP_FILES :=	utils/fix_dfile.pl
GREP_RECURSIVE :=	utils/grep-recursive
REPLACELINE :=		utils/replaceline

# Directory paths
SUBDIRS :=							\
			getctypeinfo				\
			include					\
			include/c++				\
			include_internal			\
			include_internal/c++			\
			runcmd					\
			share					\
			siltgraph				\
			utils
TEST_SUBDIRS :=							\
			test/siltgraph/linegraph-000		\
			test/siltgraph/histogram-000		\
			test/siltgraph/clusteredhistogram-000
BIN_DIR := $(PREFIX)/bin
INCLUDE_DIR := $(PREFIX)/include
LIB_DIR := $(PREFIX)/lib
SHARE_DIR := $(PREFIX)/share/silt

# Flags
CPPFLAGS := $(SYS_CPPFLAGS) -Iinclude -Iinclude_internal
CFLAGS := $(SYS_CFLAGS) -Wall
CXXFLAGS := $(SYS_CXXFLAGS) -Wall
LDFLAGS := $(SYS_LDFLAGS)

# Commands
C2D =		@set -e; rm -f $(1);					\
		$(CC) -MM $(CPPFLAGS)					\
		$(2) > $(1).$$$$;					\
		$(FIX_DEP_FILES) $(1).$$$$ $(1) $(2);			\
		rm -f $(1).$$$$
CPP2D =		@set -e; rm -f $(1);					\
		$(CC) -MM $(CPPFLAGS)					\
		$(2) > $(1).$$$$;					\
		$(FIX_DEP_FILES) $(1).$$$$ $(1) $(2);			\
		rm -f $(1).$$$$
C2O =		$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $(1) $(2)
CPP2O =		$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $(1) $(2)
C2EXE =		$(CC) -o $(1) $(2) $(LDFLAGS)
CPP2EXE =	$(CXX) -o $(1) $(2) $(LDFLAGS)
O2A =		$(AR) rcs $(1) $(2)
INSTALL_BIN =	$(INSTALL) -m 755 $(1) $(BIN_DIR)
INSTALL_CH =	$(INSTALL) -m 644 $(1) $(INCLUDE_DIR)
INSTALL_CPPH =	$(INSTALL) -m 644 $(1) $(INCLUDE_DIR)/c++
INSTALL_LIB =	$(INSTALL) -m 644 $(1) $(LIB_DIR)
INSTALL_SHARE =	$(INSTALL) -m 644 $(1) $(SHARE_DIR)

# Set all as the default target
all:

# Include local makefiles
include $(foreach d,$(SUBDIRS),$(d)/local.mk)				\
	$(foreach d,$(TEST_SUBDIRS),$(d)/local.mk)

all: $(foreach d,$(SUBDIRS),$(d)/all)

clean: $(foreach d,$(SUBDIRS),$(d)/clean)
	rm -f *~

install: all installdirs $(foreach d,$(SUBDIRS),$(d)/install)

deps:

realclean: clean $(foreach d,$(SUBDIRS),$(d)/realclean)

dist:
	rm -rf temp/$(DIST_NAME) temp/$(DIST_NAME).tgz
	mkdir temp/$(DIST_NAME)
	cp -a `find . -maxdepth 1 -mindepth 1 | grep -v ./temp`		\
		temp/$(DIST_NAME)
	rm -rf `find temp/$(DIST_NAME) -name .svn`
	cd temp/$(DIST_NAME); ./configure.pl; make realclean
	rm -f temp/$(DIST_NAME)/system.mk
	cd temp; tar cfz $(DIST_NAME).tgz $(DIST_NAME)

test:	$(foreach d,$(TEST_SUBDIRS),$(d)/all)				\
	$(foreach d,$(TEST_SUBDIRS),$(d)/test)

doxygen:
	$(DOXYGEN) doxygen.config

findattn:
	$(GREP_RECURSIVE) --ignore-dir=.svn,./temp --ignore-ft=o,d ATTN

help:
	@echo Primary Targets:
	@echo '  all                 build all targets in SiLT'
	@echo '  clean               clean project directories'
	@echo '  dist                create a distribution of SiLT at'
	@echo '                      temp/$(DIST_NAME).tgz'
	@echo '  install             install SiLT'
	@echo '  test                run tests for SiLT'
	@echo Secondary Targets
	@echo '  deps                build *.d files'
	@echo '  doxygen             create doxygen documentation'
	@echo '  findattn            find ATTN in source files'
	@echo '  realclean           completely clean project directories'
	@echo Subdirectory Targets
	@echo '  <dir>/all           make all targets in <dir>'
	@echo '  <dir>/clean         clean <dir>'
	@echo '  <dir>/install       install <dir>'
	@echo '  <dir>/realclean     completely clean <dir>'
	@echo '  test/<subdir>/test  perform tests for test/<subdir>'

installdirs:
	mkdir -p $(BIN_DIR)
	chmod 755 $(BIN_DIR)
	mkdir -p $(INCLUDE_DIR)
	chmod 755 $(INCLUDE_DIR)
	mkdir -p $(INCLUDE_DIR)/c++
	chmod 755 $(INCLUDE_DIR)/c++
	mkdir -p $(LIB_DIR)
	chmod 755 $(LIB_DIR)
	mkdir -p $(SHARE_DIR)
	chmod 755 $(SHARE_DIR)

%.d: %.c
	$(call C2D,$@,$<)

%.d: %.cpp
	$(call CPP2D,$@,$<)

%.o: %.c
	$(call C2O,$@,$<)

%.o: %.cpp
	$(call CPP2O,$@,$<)

%.a:
	$(call O2A,$@,$^)

%.bininstall: %
	$(call INSTALL_BIN,$*)

%.h.chinstall: %.h
	$(call INSTALL_CH,$<)

%.h.cpphinstall: %.h
	$(call INSTALL_CPPH,$<)

%.a.ainstall: %.a
	$(call INSTALL_LIB,$<)

%.pm.pminstall: %.pm
	$(call INSTALL_LIB,$<)

%.shareinstall: %
	$(call INSTALL_SHARE,$*)

.PHONY: doxygen clean realclean all
